package com.longcai.controller;


import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.collect.Lists;
import com.longcai.entity.sys.SysPermission;
import com.longcai.service.SysPermissionService;
import com.longcai.util.LoginUser;
import com.longcai.util.UserUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author ZJ
 * @since 2019-03-16
 */
@Api(tags = "权限")
@RestController
@RequestMapping("/permissions/")
public class SysPermissionController {

    @Autowired
    private SysPermissionService sysPermissionService;

    @ApiOperation(value = "当前登录用户拥有的权限")
    @GetMapping(value = "current")
    public List<SysPermission> permissionsCurrent() {
        // 当前用户
        LoginUser loginUser = UserUtil.getLoginUser();
        List<SysPermission> sysPermissions = loginUser.getPermissions();
        // lambda表达式获取所有菜单
        final List<SysPermission> permissions = sysPermissions.stream().
                filter(p -> p.getType().equals(1)).collect(Collectors.toList());

        // lambda表达式获取所有左侧父类菜单栏
        List<SysPermission> parentMenu = permissions.stream().filter(m -> m.getParentId().equals(0)).collect(Collectors.toList());
        parentMenu.parallelStream().forEach(m -> {
            this.setChild(m, permissions);
        });
        return parentMenu;
    }

    /**
     * 设置子元素
     *
     * @param m
     * @param permissions
     */
    private void setChild(SysPermission m, List<SysPermission> permissions) {
        // 获取父类菜单中的子类菜单
        List<SysPermission> child = permissions.stream().filter(p -> p.getParentId().equals(m.getId())).collect(Collectors.toList());
        m.setChild(child);
        if (!CollectionUtils.isEmpty(child)) {
            child.parallelStream().forEach(c -> {
                this.setChild(c, permissions);
            });
        }
    }

    @GetMapping(value = "listAll")
    @ApiOperation(value = "菜单列表")
    @PreAuthorize("hasAuthority('sys:menu:query')")
    public List<SysPermission> permissionsList() {
    	QueryWrapper<SysPermission> w = new QueryWrapper<SysPermission>();
    	w.orderByAsc("sort");
        List<SysPermission> permissionsAll = this.sysPermissionService.selectList(w);

        List<SysPermission> list = Lists.newArrayList();
        setPermissionsList(0, permissionsAll, list);

        return list;
    }

    public void setPermissionsList(Integer pId, List<SysPermission> permissionsAll, List<SysPermission> list) {
        permissionsAll.forEach(p -> {
            if (p.getParentId().equals(pId)) {
                list.add(p);
                if (permissionsAll.stream().filter(a -> a.getParentId().equals(p.getId())).findAny() != null) {
                    this.setPermissionsList(p.getId(), permissionsAll, list);
                }
            }
        });
    }

    /**
     * 校验权限
     *
     * @return
     */
    @GetMapping("owns")
    @ApiOperation(value = "校验当前用户的权限")
    public Set<String> ownsPermission() {
        List<SysPermission> permissions = UserUtil.getLoginUser().getPermissions();
        if (CollectionUtils.isEmpty(permissions)) {
            return Collections.emptySet();
        }

        return permissions.parallelStream().filter(p -> !StringUtils.isEmpty(p.getPermission()))
                .map(SysPermission::getPermission).collect(Collectors.toSet());
    }

    /**
     * 一级菜单
     *
     * @return
     */
    @GetMapping("parents")
    @ApiOperation(value = "一级菜单")
    @PreAuthorize("hasAuthority('sys:menu:query')")
    public List<SysPermission> parentMenu() {
        List<SysPermission> parents = this.sysPermissionService.listParents();

        return parents;
    }

    @GetMapping("{id}")
    @ApiOperation(value = "根据菜单id获取菜单")
    @PreAuthorize("hasAuthority('sys:menu:query')")
    public SysPermission get(@PathVariable Integer id) {
        return this.sysPermissionService.getById(id);
    }

    /**
     * 修改菜单
     *
     * @param sysPermission
     */
    @PutMapping(value = "updatePermission")
    @ApiOperation(value = "修改菜单")
    @PreAuthorize("hasAuthority('sys:menu:add')")
    public void updatePermission(@RequestBody SysPermission sysPermission) {
        this.sysPermissionService.updatePermission(sysPermission);
    }

    @DeleteMapping("{id}")
    @ApiOperation(value = "删除菜单")
    @PreAuthorize("hasAuthority('sys:menu:del')")
    public void delete(@PathVariable Integer id) {
        this.sysPermissionService.deleteById(id);
    }

    @PostMapping(value = "savePermission")
    @ApiOperation(value = "保存菜单")
    @PreAuthorize("hasAuthority('sys:menu:add')")
    public void save(@RequestBody SysPermission sysPermission) {
        this.sysPermissionService.insert(sysPermission);
    }

    @GetMapping(value = "roleId")
    @ApiOperation(value = "根据角色id获取权限")
    @PreAuthorize("hasAnyAuthority('sys:menu:query','sys:role:query')")
    public List<SysPermission> listByRoleId(Integer roleId) {
        return this.sysPermissionService.listByRoleId(roleId);
    }

    @GetMapping("/all")
    @ApiOperation(value = "所有菜单")
    @PreAuthorize("hasAuthority('sys:menu:query')")
    public JSONArray permissionsAll() {
        List<SysPermission> permissionsAll = this.sysPermissionService.selectList(null);
        JSONArray array = new JSONArray();
        setPermissionsTree(0, permissionsAll, array);

        return array;
    }

    /**
     * 菜单树
     *
     * @param pId
     * @param permissionsAll
     * @param array
     */
    private void setPermissionsTree(Integer pId, List<SysPermission> permissionsAll, JSONArray array) {
        permissionsAll.forEach(a -> {
            if (a.getParentId().equals(pId)) {
                String string = JSONObject.toJSONString(a);
                JSONObject parent = (JSONObject) JSONObject.parse(string);
                array.add(parent);

                if (permissionsAll.stream().filter(p -> p.getParentId().equals(a.getId())).findAny() != null) {
                    JSONArray child = new JSONArray();
                    parent.put("child", child);
                    setPermissionsTree(a.getId(), permissionsAll, child);
                }
            }
        });
    }
}

